<?php

namespace Henan\ThinkSdk\traits;


use think\facade\Db;
use think\Model;
use Exception;

/**
 * 回收站特征
 */
trait RcyModelTrait
{
    /**
     * 回收操作人ID
     * @var string|int|null
     */
    protected static string|int|null $uid = null;

    protected static function onAfterInsert(Model $model): void
    {
        self::recycleInsert($model);
    }

    protected static function onAfterUpdate(Model $model): void
    {
        self::recycleUpdate($model);
    }

    protected static function onAfterDelete(Model $model): void
    {
        self::recycleDelete($model);
    }

    /**
     * 回收新增
     * @param Model $model
     * @return void
     * @throws Exception
     */
    public static function recycleInsert(Model $model): void
    {
        self::recycleEvent($model, 0);
    }

    /**
     * 回收更新
     * @param Model $model
     * @return void
     * @throws Exception
     */
    public static function recycleUpdate(Model $model): void
    {
        self::recycleEvent($model, 1);
    }

    /**
     * 回收删除
     * @param Model $model
     * @return void
     * @throws Exception
     */
    public static function recycleDelete(Model $model): void
    {
        self::recycleEvent($model, 2);
    }

    /**
     * 回收处理事件
     * @param Model $model
     * @param int $type
     * @return bool
     * @throws Exception
     */
    private static function recycleEvent(Model $model, int $type): bool
    {
        try {
            $oldData = empty($model->getOrigin()) ? null : json_encode($model->getOrigin(), 320);
            $newData = empty($model->getData()) ? null : json_encode($model->getData(), 320);
            switch ($type) {
                case 0:
                    // 新增
                    $oldData = null;
                    break;
                case 1:
                    // 更新
                    if ($oldData == $newData) return false;
                    break;
                case 2:
                    // 删除
                    $newData = null;
                    break;
                default:
                    throw new Exception('类型错误');
            }
            // 记录操作记录
            self::getRecycleDb()->insert([
                'table' => self::getTable(),
                'tid' => $model[$model->pk],
                'type' => $type,
                'old' => $oldData,
                'new' => $newData,
                'uid' => self::$uid,
                'create_time' => date('Y-m-d H:i:s')
            ]);
        } catch (\Exception $e) {
            throw new Exception($e->getMessage());
        }
        return true;
    }

    /**
     * 获取回收站连接对象
     * @return \think\db\BaseQuery
     * @throws Exception
     */
    private static function getRecycleDb(): \think\db\BaseQuery
    {
        try {
            $connect = config('sdk.RcyModelTrait')['connect'] ?? null;
            $table = config('sdk.RcyModelTrait')['table'] ?? null;
            if (empty($connect)) throw new Exception("回收数据库名未配置，请前往sdk配置文件进行配置");
            if (empty($table)) throw new Exception("回收数据表未配置，请前往sdk配置文件进行配置");
            $db = Db::connect($connect);
            if (empty($db->query("show tables like '{$table}'"))) {
                $sql = <<<EOT
CREATE TABLE `{$table}` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '日志id',
  `table` varchar(125) COMMENT '操作表名',
  `tid` int(11) COMMENT '数据ID',
  `type` tinyint(1) default 0 comment '类型：0新增,1更新,2删除',
  `old` text COMMENT '旧数据',
  `new` text COMMENT '新数据',
  `uid` varchar(32) COMMENT '操作人ID',
  `create_time` datetime  COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='数据回收表 - {$table}';
EOT;
                $db->execute($sql);
            }
            return $db->table($table);
        } catch (Exception $e) {
            throw new Exception($e->getMessage());
        }
    }
}